#ifndef _XBASE_TABLE_INFO_CACHE_HPP_
#define _XBASE_TABLE_INFO_CACHE_HPP_

#include <map>
#include <list>

#include <boost/intrusive_ptr.hpp>
#include <boost/system/error_code.hpp>

#include "protocol.hpp"
#include "async_write.hpp"
#include "sync_handler.hpp"
#include "session_manager.hpp"
#include "async_module_base.hpp"

namespace xbase
{
	class table_info_cache
		: public async_module_base<io_service_pool::xbase_level, io_service_pool::xbase_level>
	{
	public:
		typedef async_module_base<io_service_pool::xbase_level, io_service_pool::xbase_level> base_type;
		typedef table_info_cache this_type;
		typedef boost::intrusive_ptr<this_type> ptr_type;

		typedef session_manager::endpoint_type endpoint_type;

		typedef protocol::packet_type<protocol::TABLE_INFO_REQ>::type request_packet_type;
		typedef protocol::packet_type<protocol::TABLE_INFO_REQ>::ptr_type request_packet_ptr;
		typedef protocol::packet_type<protocol::TABLE_INFO_RESP>::type response_packet_type;
		typedef protocol::packet_type<protocol::TABLE_INFO_RESP>::ptr_type response_packet_ptr;

		typedef boost::system::error_code error_code;

		typedef protocol::table_info_ptr table_info_ptr;
		typedef std::map<std::string, table_info_ptr> table_info_map;

		typedef boost::function<void(table_info_ptr, const error_code&)> handler_type;
		typedef std::list<handler_type> handler_list;
		typedef std::map<std::string, handler_list> handler_map;

		typedef basic_sync_handler<protocol::table_info_ptr> sync_handler_type;

	public:
		table_info_cache(io_service_pool &pool,
			const endpoint_type &endpoint,
			session_manager &session_manager_ref)
			: base_type(pool),
			m_master_server_endpoint(endpoint),
			m_session_manager(session_manager_ref)
		{
		}

		void async_get_table_info(const std::string &table_name, handler_type handler, bool hard = false);
	private:
		void on_get_table_info_response(std::string table_name,
			protocol::packet_ptr pkt_ptr,
			const error_code &ec);

		// 缓冲模块不需要ptr_type持有
		this_type *this_ptr() {
			return this;
		}

	private:
		endpoint_type m_master_server_endpoint;
		table_info_map m_table_info_map;
		session_manager &m_session_manager;

		boost::mutex m_mutex;
		handler_map m_request_map;
	};

	typedef table_info_cache::ptr_type table_info_cache_ptr;
}

#endif
